/* Includes ------------------------------------------------------------------*/
#include "MyApplication.h"

/* Private define-------------------------------------------------------------*/
#define SET_CLK HAL_GPIO_WritePin(TM1620_CLK_GPIO_Port,TM1620_CLK_Pin,GPIO_PIN_SET)
#define CLR_CLK HAL_GPIO_WritePin(TM1620_CLK_GPIO_Port,TM1620_CLK_Pin,GPIO_PIN_RESET)

#define SET_DIN HAL_GPIO_WritePin(TM1620_DIN_GPIO_Port,TM1620_DIN_Pin,GPIO_PIN_SET)
#define CLR_DIN HAL_GPIO_WritePin(TM1620_DIN_GPIO_Port,TM1620_DIN_Pin,GPIO_PIN_RESET)

#define SET_STB HAL_GPIO_WritePin(TM1620_STB_GPIO_Port,TM1620_STB_Pin,GPIO_PIN_SET)
#define CLR_STB HAL_GPIO_WritePin(TM1620_STB_GPIO_Port,TM1620_STB_Pin,GPIO_PIN_RESET)

uint8_t Disp_Code[16] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};

/* Private variables----------------------------------------------------------*/
static void TM1620_Write_Byte(uint8_t );
static void TM1620_Init(void);
static void Disp_Hex(Disp_NUM_t ,uint8_t ,Disp_DP_Status_t );
static void Disp_Other(Disp_NUM_t ,uint8_t ,Disp_DP_Status_t );
static void Disp_Clr(void);
/* Public variables-----------------------------------------------------------*/
Display_t Display = 
{
    Brightness_level_3,
    Display_SHT30,

    TM1620_Init,
    Disp_Hex,
    Disp_Other,
    Disp_Clr
};
/* Private function prototypes------------------------------------------------*/

/*
* @name   TM1620_Write_Byte
* @brief  TM1620写入字节
* @param  dat：待写入的数据或命令
* @retval None   
*/
static void TM1620_Write_Byte(uint8_t dat)
{
    static uint8_t i;
    //先拉低STB
    CLR_STB;
    for(i=0;i<8;i++)
    {
        //拉低CLK
        CLR_CLK;
        //放数据
        if((dat&0x01) == 1)
        {
            SET_DIN;
        }
        else
        {
            CLR_DIN;
        }
        //拉高CLK，TM1620读取数据位
        SET_CLK;
        //数据右移，准备下一个数据位
        dat = dat >> 1;
        __nop();
    }
}

/*
* @name   TM1620_Init
* @brief  TM1620初始化
* @param  None
* @retval None   
*/
static void TM1620_Init()
{
    uint8_t i;
    //设置显示模式——6位8段
    TM1620_Write_Byte(Disp_Mode_GRID6_SEG8);
    SET_STB;

    //设置数据命令——自动地址增加
    TM1620_Write_Byte(Write_Data_Addr_Auto_Add);
    SET_STB;
    
    //设置显示地址
    TM1620_Write_Byte(Disp_SFR_Addr_00H);

    //写入数据——TM1620上电清零操作
    for(i=0;i<12;i++)
    {
        TM1620_Write_Byte(0x00);
    }
    SET_STB;

    //显示辉度
    TM1620_Write_Byte(Display.Brightness);
    SET_STB;
}

/*
* @name   Disp_Hex
* @brief  TM1620显示数据
* @param  Disp_NUM：指定显示的数码管
          Dat：要显示的数据
          Disp_DP_Status：是否带小数点
* @retval None   
*/
static void Disp_Hex(Disp_NUM_t Disp_NUM,uint8_t Dat,Disp_DP_Status_t Disp_DP_Status)
{
    //设置显示模式——6位8段
    TM1620_Write_Byte(Disp_Mode_GRID6_SEG8);
    SET_STB;

    //设置数据命令——固定地址
    TM1620_Write_Byte(Write_Data_Addr_Fix);
    SET_STB;

    //设置显示地址
    TM1620_Write_Byte(Disp_NUM);

    //判断小数点状态，并显示数据
    if(Disp_DP_Status == Disp_DP_ON)
    {
        TM1620_Write_Byte(Disp_Code[Dat]+0x80);
    }
    else
    {
        TM1620_Write_Byte(Disp_Code[Dat]);
    }
    SET_STB;

    //显示辉度
    TM1620_Write_Byte(Display.Brightness);
    SET_STB;
}

/*
* @name   Disp_Other
* @brief  TM1620显示数据
* @param  Disp_NUM：指定显示的数码管
          Dat：要显示的数据
          Disp_DP_Status：是否带小数点
* @retval None   
*/
static void Disp_Other(Disp_NUM_t Disp_NUM,uint8_t Dat,Disp_DP_Status_t Disp_DP_Status)
{
    //设置显示模式——6位8段
    TM1620_Write_Byte(Disp_Mode_GRID6_SEG8);
    SET_STB;

    //设置数据命令——固定地址
    TM1620_Write_Byte(Write_Data_Addr_Fix);
    SET_STB;

    //设置显示地址
    TM1620_Write_Byte(Disp_NUM);

    //判断小数点状态，并显示数据
    if(Disp_DP_Status == Disp_DP_ON)
    {
        TM1620_Write_Byte(Dat+0x80);
    }
    else
    {
        TM1620_Write_Byte(Dat);
    }
    SET_STB;

    //显示辉度
    TM1620_Write_Byte(Display.Brightness);
    SET_STB;
}

/*
* @name   Disp_Clr
* @brief  数码管清除
* @param  Disp_NUM：指定显示的数码管
          Dat：要显示的数据
          Disp_DP_Status：是否带小数点
* @retval None   
*/
static void Disp_Clr()
{
    Display.Disp_Other(Disp_NUM_1,0x00,Disp_DP_OFF);
    Display.Disp_Other(Disp_NUM_2,0x00,Disp_DP_OFF);
    Display.Disp_Other(Disp_NUM_3,0x00,Disp_DP_OFF);
    Display.Disp_Other(Disp_NUM_4,0x00,Disp_DP_OFF);
    Display.Disp_Other(Disp_NUM_5,0x00,Disp_DP_OFF);
    Display.Disp_Other(Disp_NUM_6,0x00,Disp_DP_OFF);
}
/********************************************************
  End Of File
********************************************************/
